home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_1 / breq / breq.c < prev    next >
C/C++ Source or Header  |  1994-09-09  |  16KB  |  522 lines

  1. /******************************************************************************
  2. *                                          *
  3. *  BReq: opens a window on a custom screen with two gadgets for a startup     *
  4. *     option selection. Originally intended for use with NetBSD-Amiga.     *
  5. *                                          *
  6. * Copyright (c)1994 by Eric R. Augustine (voodoo@well.sf.ca.us)               *
  7. *                                          *
  8. * This is Copyrighted FreeWare so you may do with it as you wish as long as   *
  9. * any distribution contains all original sources and documentation and that   *
  10. * distribution is not done for the purpose of profitable gains.  The author   *
  11. * accepts no responsibility for  any damage as    a result of the use of this   *
  12. * program nor  does he make any claims or garantees as to what this program   *
  13. * can do.                                      *
  14. *                                          *
  15. ******************************************************************************/
  16.  
  17. #include <graphics/gfxbase.h>
  18. #include <proto/intuition.h>
  19. #include <proto/dos.h>
  20. #include <proto/exec.h>
  21. #include <proto/graphics.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #define TRUE  1
  26. #define FALSE 0
  27.  
  28. #define PALHEIGHT 512
  29. #define PALGADTOP  56
  30.  
  31. /*  these two for action based on user response or timeout
  32.  */
  33. #define SYSA 1
  34. #define SYSB 2
  35.  
  36. /*  yes I know there's already a type BOOL
  37.  */
  38. typedef int bool;
  39.  
  40. /*  library bases needed for closing the libraries at cleanup
  41.  */
  42. struct IntuitionBase *IntuitionBase;
  43. extern struct  GfxBase *GfxBase;
  44. struct Library *DosBase;
  45.  
  46. /*  build blank screen pointer
  47.  */
  48. USHORT chip BlankPoint[4] = {
  49.    0x0000, 0x0000,
  50.    0x0000, 0x0000
  51. };
  52.  
  53. /*  create gadget box:    makes a beveled box 96 pixels wide by
  54.  *  32 pixels high.
  55.  */
  56. SHORT BoxPoints[] = {
  57.     0,    0,
  58.    96,    0,
  59.    96, 32,
  60.     0, 32,
  61.     0,    0,
  62.     4,    4,
  63.    92,    4,
  64.    96,    0,
  65.    92,    4,
  66.    92, 28,
  67.    96, 32,
  68.    92, 28,
  69.     4, 28,
  70.     0, 32,
  71.     4, 28,
  72.     4,    4
  73. };
  74.  
  75. /*  make gadget borders from boxes
  76.  */
  77. struct Border BRBorder = {
  78.    0,            /* LeftEdge   */
  79.    0,            /* TopEdge      */
  80.    1,            /* FrontPen   */
  81.    0,            /* BackPen      */
  82.    JAM1,        /* DrawMode   */
  83.    16,            /* Count      */
  84.    BoxPoints,        /* XY      */
  85.    NULL,        /* NextBorder */
  86. };
  87.  
  88. /*  build left gadget
  89.  */
  90. UBYTE BRLeftString[] = "A";
  91.  
  92. struct IntuiText BRLeftText = {
  93.    1,            /* FrontPen  */
  94.    0,            /* BackPen     */
  95.    JAM1,        /* DrawMode  */
  96.    8,            /* LeftEdge  */
  97.    12,            /* TopEdge     */
  98.    NULL,        /* ITextFont */
  99.    BRLeftString,    /* IText     */
  100.    NULL         /* NextText  */
  101. };
  102.  
  103. struct Gadget BRLeftGad = {
  104.    NULL,        /* NextGadget    */
  105.    50,            /* LeftEdge      */
  106.    157,         /* TopEdge         */
  107.    96,            /* Width         */
  108.    32,            /* Height         */
  109.    GADGHCOMP,        /* Flags         */
  110.    GADGIMMEDIATE|   /* Activation    */
  111.    RELVERIFY,
  112.    BOOLGADGET,        /* GadgetType    */
  113.    (APTR)&BRBorder, /* GadgetRender  */
  114.    NULL,        /* SelectRender  */
  115.    &BRLeftText,     /* GadgetText    */
  116.    NULL,        /* MutualExclude */
  117.    NULL,        /* SpecialInfo   */
  118.    0,            /* GadgetID      */
  119.    NULL         /* UserData      */
  120. };
  121.  
  122. /*  build comment string for left button
  123.  */
  124. UBYTE BRLeftComment[] = " ";
  125.  
  126. struct IntuiText BRLeftCommentText = {
  127.    1,            /* FrontPen  */
  128.    0,            /* BackPen     */
  129.    JAM1,        /* DrawMode  */
  130.    8,            /* LeftEdge  */
  131.    12,            /* TopEdge     */
  132.    NULL,        /* ITextFont */
  133.    BRLeftComment,   /* IText     */
  134.    NULL         /* NextText  */
  135. };
  136.  
  137. /*  build right gadget
  138.  */
  139. UBYTE BRRightString[] = "B";
  140.  
  141. struct IntuiText BRRightText = {
  142.    1,            /* FrontPen  */
  143.    0,            /* BackPen     */
  144.    JAM1,        /* DrawMode  */
  145.    8,            /* LeftEdge  */
  146.    12,            /* TopEdge.  */
  147.    NULL,        /* ITextFont */
  148.    BRRightString,   /* IText     */
  149.    NULL         /* NextText  */
  150. };
  151.  
  152. struct Gadget BRRightGad = {
  153.    &BRLeftGad,        /* NextGadget */
  154.    50,            /* LeftEdge   */
  155.    210,         /* TopEdge      */
  156.    96,            /* Width      */
  157.    32,            /* Height      */
  158.    GADGHCOMP,        /* Flags      */
  159.    GADGIMMEDIATE|   /* Activation */
  160.    RELVERIFY,
  161.    BOOLGADGET,        /* GadgetType    */
  162.    (APTR)&BRBorder, /* GadgetRender  */
  163.    NULL,        /* SelectRender  */
  164.    &BRRightText,    /* GadgetText    */
  165.    NULL,        /* MutualExclude */
  166.    NULL,        /* SpecialInfo   */
  167.    0,            /* GadgetID      */
  168.    NULL         /* UserData      */
  169. };
  170.  
  171. /*  build comment string for right button
  172.  */
  173. UBYTE BRRightComment[] = " ";
  174.  
  175. struct IntuiText BRRightCommentText = {
  176.    1,            /* FrontPen  */
  177.    0,            /* BackPen     */
  178.    JAM1,        /* DrawMode  */
  179.    8,            /* LeftEdge  */
  180.    12,            /* TopEdge     */
  181.    NULL,        /* ITextFont */
  182.    BRRightComment,  /* IText     */
  183.    NULL         /* NextText  */
  184. };
  185.  
  186. /*  BReq's window
  187.  */
  188. struct Window *BRWin;
  189.  
  190. /*  Vanilla required new window
  191.  */
  192. struct NewWindow NWin = {
  193.    0,               /* LeftEdge    */
  194.    0,               /* TopEdge     */
  195.    640,            /* Width       */
  196.    400,            /* Height      */
  197.    0,               /* DetailPen   */
  198.    1,               /* BlockPen    */
  199.    CLOSEWINDOW|        /* IDCMPFlags  */
  200.    INTUITICKS|
  201.    GADGETDOWN|
  202.    VANILLAKEY|
  203.    MOUSEBUTTONS|
  204.    MOUSEMOVE,
  205.    WFLG_SMART_REFRESH| /* Flags       */
  206.    WFLG_BORDERLESS|
  207.    RMBTRAP|
  208.    REPORTMOUSE|
  209.    ACTIVATE,
  210.    &BRRightGad,        /* FirstGadget */
  211.    NULL,           /* CheckMark   */
  212.    NULL,           /* Title       */
  213.    NULL,           /* Screen      */
  214.    NULL,           /* BitMap      */
  215.    0,               /* MinWidth    */
  216.    0,               /* MinHeight   */
  217.    640,            /* MaxWidth    */
  218.    400,            /* MaxHeight   */
  219.    CUSTOMSCREEN        /* Type          */
  220. };
  221.  
  222. /*  BReq's custom screen
  223.  */
  224. struct Screen *BScreen;
  225.  
  226. /*  new screen structure - could use OpenScreenTags()
  227.  *  but, I want to account for PAL modes as well.
  228.  */
  229. struct NewScreen NScreen = {
  230.    0,               /* LeftEdge     */
  231.    0,               /* TopEdge      */
  232.    640,            /* Width        */
  233.    400,            /* Height       */
  234.    4,               /* Depth        */
  235.    0,               /* DetailPen    */
  236.    1,               /* BlockPen     */
  237.    HIRES|LACE,           /* ViewModes    */
  238.    CUSTOMSCREEN,       /* Type           */
  239.    NULL,           /* Font           */
  240.    NULL,           /* DefaultTitle */
  241.    NULL,           /* Gadgets      */
  242.    NULL            /* CustomBitMap */
  243. };
  244.  
  245. /*  readargs structure for user preferences
  246.  */
  247. struct internal_args {
  248.    char  *timeout;         /* idle time timeout       */
  249.    char  *blank;         /* idle time blank screen       */
  250.    const char *defresponse;  /* select default for timeout */
  251.    char  *buttons;         /* title individual buttons   */
  252.    bool  reverse;         /* reverse colors           */
  253.    char  *atext;         /* itext to left button       */
  254.    char  *btext;         /* itext to right button       */
  255.    char  *sysa;          /* system call string top       */
  256.    char  *sysb;          /* system call string bottom  */
  257. };
  258.  
  259. /*  avoid larger stdio code by using this very simple printing routine
  260.  *  using just dos library routines and string.
  261.  */
  262. void error(char *errstr) {
  263.    Write(Output(),errstr,strlen(errstr));
  264. }
  265.  
  266. main(int argc, char *argv[]) {
  267.    APTR   address;            /* IDCMP response address for gadgets      */
  268.    bool   user_response = FALSE;    /* whether or not user has made a response */
  269.    bool   BLANKDONE = FALSE;        /* blanker currently in process           */
  270.    char   *buttonstr;            /* modifiable button titles for user       */
  271.    int      action;            /* action to take once BReq closes           */
  272.    int      hmode = 0;            /* height of comments based on display     */
  273.    ULONG  class;            /* IDCMP message Class               */
  274.    ULONG  seconds;            /* Seconds counted by IDCMP            */
  275.    ULONG  startsecs;            /* seconds at start of BReq            */
  276.    ULONG  blanksecs;            /* seconds to blank                */
  277.    ULONG  blank_start;            /* same as startsecs until blank           */
  278.    ULONG  user_secs;            /* modifiable timeout value            */
  279.    USHORT code;             /* IDCMP keycodes via VANILLAKEY           */
  280.    struct IntuiMessage *BRMessage;  /* BReq's IDCMP Message port               */
  281.    void   CleanUp(void);            /* close screen and libraries              */
  282.  
  283. /*  init command line args
  284.  */
  285.    struct internal_args ia = { "31536000",                        /* timeout,     one year       */
  286.                    "180",                             /* blank,       three minutes  */
  287.                    "A",                               /* defresponse, bottom gadget  */
  288.                    "NetBSD|AmigaOS",                  /* buttons,     titles         */
  289.                    FALSE,                  /* reverse,      reverse     */
  290.                    " ",                               /* atext,       top comment    */
  291.                    " ",                               /* btext,       bottom comment */
  292.                    "sys:loadbsd sys:vmunix -a",       /* sysa,        load NetBSD    */
  293.                    NULL };                  /* sysb,      no task     */
  294.  
  295. /*  open libraries
  296.  */
  297.    if(!(DosBase = (struct Library *)OpenLibrary("dos.library",0))) {
  298.       error("BReq: can't open dos.library\n");
  299.       exit(1);
  300.    }
  301.    if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))) {
  302.       error("BReq: can't open intuition.library\n");
  303.       exit(1);
  304.    }
  305.    if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) {
  306.       error("BReq: can't open graphics.library\n");
  307.       exit(1);
  308.    }
  309.  
  310. /*  get user preferences:  use AmigaOS RDArgs rather than C standard.
  311.  */
  312.    (struct RDArgs *)ReadArgs("TIMEOUT/K,BLANK/K,DEFAULT/K,BUTTONS/K,REVERSE/S,ATEXT/K,BTEXT/K,SYSA/K,SYSB/K", (long *)&ia, NULL);
  313.  
  314. /*  get current system seconds from intuition
  315.  */
  316.    CurrentTime(&startsecs,NULL);
  317.  
  318. /*  copy starting seconds for blanker
  319.  */
  320.    blank_start = startsecs;
  321.  
  322.  
  323. /*  check for user specified default response: compare the character (string)
  324.  *  from the command line with the acceptable values.  if failure then use
  325.  *  internal default value.
  326.  */
  327.    if((strcmp(ia.defresponse,"A") == 0) || (strcmp(ia.defresponse,"a") == 0))
  328.       action = SYSA;
  329.    else if((strcmp(ia.defresponse,"B") == 0) || (strcmp(ia.defresponse,"b") == 0))
  330.       action = SYSB;
  331.    else {
  332.       error("BReq: invalid DEFAULT \"");
  333.       error((char *)ia.defresponse);
  334.       error("\", using \"A\".\n");
  335.       action = SYSA;
  336.    }
  337.  
  338. /*  get timeout value: for some reason the intuitive way of doing this direct
  339.  *  from the command line didn't work so using atoi() (clib) to do the job.
  340.  */
  341.    user_secs  = atoi(ia.timeout);
  342.    blanksecs  = atoi(ia.blank);
  343.  
  344. /*  make gadget titles.  use routines from clib (defined in string.h) to get
  345.  *  individual gadgets from one string.  (using "|" for compatibility to 1.12)
  346.  */
  347.    if(strstr(ia.buttons,"|") == NULL)
  348.       error("BReq: \"|\" separater missing, using default gadgets.\n");
  349.    else {
  350.       BRLeftText.IText    = strtok(ia.buttons,"|");
  351.       buttonstr     = strchr(ia.buttons,'|');
  352.       BRRightText.IText = strtok(buttonstr,NULL);
  353.    }
  354.  
  355. /*  make gadget comments
  356.  */
  357.    BRLeftCommentText.IText  = ia.atext;
  358.    BRRightCommentText.IText = ia.btext;
  359.  
  360. /*  check for PAL screen mode and set screen, window and
  361.  *  gadgets accordingly.
  362.  */
  363.    if(GfxBase->DisplayFlags & PAL) {
  364.       NScreen.Height     = PALHEIGHT;
  365.       NWin.Height     = PALHEIGHT;
  366.       BRLeftGad.TopEdge  = PALGADTOP + 157;
  367.       BRRightGad.TopEdge = PALGADTOP + 210;
  368.       hmode = PALGADTOP;
  369.    }
  370.  
  371. /*  do gui:  open the screen then the window on which the gadgets are drawn.
  372.  *  use IDCMP to count passing seconds and get user response, if any.  set
  373.  *  action value based on user response or execute default on timeout.
  374.  */
  375.   if(!(BScreen = OpenScreen(&NScreen))) {
  376.      error("BReq: can't open screen\n");
  377.      exit(2);
  378.   }
  379.  
  380. /*  if user wants reverse screen just switch bits.  for white, 11 was used
  381.  *  instead of 15 (brightest) since 15 was too bright.
  382.  */
  383.    if(ia.reverse) {
  384.       SetRGB4(&BScreen->ViewPort,1,11,11,11);
  385.       SetRGB4(&BScreen->ViewPort,0,0,0,0);
  386.    }
  387.    else {
  388.       SetRGB4(&BScreen->ViewPort,1,0,0,0);
  389.       SetRGB4(&BScreen->ViewPort,0,8,9,9);
  390.    }
  391.  
  392. /*  set the window's screen to the CUSTOMSCREEN
  393.  */
  394.    NWin.Screen = BScreen;
  395.  
  396. /*  open BReq's window
  397.  */
  398.    if(!(BRWin = (struct Window *)OpenWindow(&NWin))) {
  399.       error("BReq: can't open window\n");
  400.       CloseLibrary((struct Library *)IntuitionBase);
  401.       CloseLibrary((struct Library *)DosBase);
  402.       CloseLibrary((struct Library *)GfxBase);
  403.       CloseScreen(BScreen);
  404.       exit(3);
  405.    }
  406.  
  407. /*  write button comments to window
  408.  */
  409.    PrintIText(BRWin->RPort,&BRLeftCommentText,150,hmode + 157);
  410.    PrintIText(BRWin->RPort,&BRRightCommentText,150,hmode + 210);
  411.  
  412. /*  event loop:  Wait() for message signals and take action based on Class
  413.  *  of IDCMP message.
  414.  */
  415.    while(!(user_response)) {                     /* wait for response or timeout */
  416.       Wait( 1 << BRWin->UserPort->mp_SigBit );   /* listen for IDCMP messages    */
  417.       while(BRMessage = (struct IntuiMessage *)GetMsg(BRWin->UserPort)) {
  418.       if(BRMessage) {
  419.      class     = BRMessage->Class;         /* IDCMP response flag        */
  420.      address = BRMessage->IAddress;      /* response address           */
  421.      seconds = BRMessage->Seconds;         /* keep track of passing time */
  422.      code     = BRMessage->Code;         /* key code here           */
  423.      ReplyMsg((struct Message *)BRMessage);  /* don't keep Intui waiting   */
  424.      switch(class) {                         /* what sort of response?     */
  425.         case INTUITICKS:             /* timer blank and timeout    */
  426.            if(((int)(seconds - startsecs)) >= user_secs) {
  427.           user_response = TRUE;      /* user response not before timeout */
  428.            }
  429.            else if((((int)(seconds - blank_start)) >= blanksecs)   /* compare to blank delay  */
  430.             && (BLANKDONE == FALSE)) {                     /* and if screen not blank */
  431.           SetRGB4(&BScreen->ViewPort,1,0,0,0);                 /* blank background */
  432.           SetRGB4(&BScreen->ViewPort,0,0,0,0);                 /* blank text       */
  433.           SetPointer(BRWin,BlankPoint,0,0,0,0);                /* blank pointer    */
  434.           BLANKDONE = TRUE;                       /* screen is blank  */
  435.            }
  436.            break;
  437.         case GADGETDOWN:             /* user pressed gadget */
  438.            user_response = TRUE;
  439.            if(address == (APTR)&BRLeftGad)   /* get which gadget    */
  440.          action = SYSA;
  441.            else
  442.          action = SYSB;
  443.            break;
  444.         case MOUSEMOVE: case MOUSEBUTTONS:     /* user used mouse */
  445.            if(BLANKDONE) {                   /* if screen blank then unblank */
  446.           if(ia.reverse)
  447.              SetRGB4(&BScreen->ViewPort,1,11,11,11);
  448.           else {
  449.              SetRGB4(&BScreen->ViewPort,1,0,0,0);
  450.              SetRGB4(&BScreen->ViewPort,0,8,9,9);
  451.           }
  452.           ClearPointer(BRWin);           /* and bring back pointer */
  453.            }
  454.            BLANKDONE = FALSE;         /* screen no longer blank */
  455.            blank_start = (int)seconds;       /* reset blanker timer */
  456.            break;
  457.         case VANILLAKEY:             /* user hit keys */
  458.            if((code == 'v') || (code == 'y')) {
  459.           user_response = TRUE;      /* user wants left gadget */
  460.           action = SYSA;
  461.            }
  462.            else if((code == 'b') || (code == 'n')) {
  463.           user_response = TRUE;      /* user wants right gadget */
  464.           action = SYSB;
  465.            }
  466.            else if(code == 13)               /* ASCII RETURN */
  467.           user_response = TRUE;      /* user wants default */
  468.            else if(code == 27) {             /* ASCII ESCape */
  469.           user_response = TRUE;      /* user wants opposite to default */
  470.           if(action == SYSB)
  471.              action = SYSA;
  472.           else
  473.              action = SYSB;
  474.            }
  475.            if(BLANKDONE) {                   /* if blank, unblank */
  476.           if(ia.reverse) {
  477.              SetRGB4(&BScreen->ViewPort,1,11,11,11);
  478.           }
  479.           else {
  480.              SetRGB4(&BScreen->ViewPort,1,0,0,0);
  481.              SetRGB4(&BScreen->ViewPort,0,8,9,9);
  482.           }
  483.           ClearPointer(BRWin);           /* and bring back pointer */
  484.            }
  485.            BLANKDONE = FALSE;         /* screen should no longer be blank */
  486.            blank_start = (int)seconds;       /* reset blanker timer */
  487.            break;
  488.         }
  489.      }
  490.       }
  491.    }
  492.  
  493. /*  take action either on user gadget selection or timeout default
  494.  */
  495.    switch(action) {
  496.       case 1:
  497.      CleanUp();
  498.      system(ia.sysa);
  499.      break;
  500.       case 2:
  501.      if(ia.sysb == NULL)
  502.         CleanUp();
  503.      else {
  504.         CleanUp();
  505.         system(ia.sysb);
  506.      }
  507.      break;
  508.    }
  509. }
  510.  
  511. /*  clean up and return to calling environment
  512.  */
  513. void CleanUp(void) {
  514.       CloseWindow(BRWin);
  515.       CloseScreen(BScreen);
  516.       CloseLibrary((struct Library *)IntuitionBase);
  517.       CloseLibrary((struct Library *)DosBase);
  518.       CloseLibrary((struct Library *)GfxBase);
  519.       return;
  520. }
  521.  
  522.